// Epart.h : Declaration of the CEpart

#pragma once

#include "resource.h"       // main symbols
#include <asptlb.h>         // Active Server Pages Definitions

#include "Epart_i.h"

using namespace ATL;



// CEpart

class ATL_NO_VTABLE CEpart :
	public CComObjectRootEx<CComMultiThreadModel>,
	public CComCoClass<CEpart, &CLSID_Epart>,
	public IDispatchImpl<IEpart, &IID_IEpart, &LIBID_EpartLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
	CEpart()
	{
		m_bOnStartPageCalled = FALSE;
	}

DECLARE_REGISTRY_RESOURCEID(IDR_EPART1)

DECLARE_NOT_AGGREGATABLE(CEpart)

BEGIN_COM_MAP(CEpart)
	COM_INTERFACE_ENTRY(IEpart)
	COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()


	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		// Initialize variables
		m_bTouched = TRUE ;
		m_bstrKey = m_bstrInitialVector = NULL ;

		return S_OK;
	}

	void FinalRelease()
	{
		::SysFreeString (m_bstrKey) ;
		::SysFreeString (m_bstrInitialVector) ;
	}

// IEpart
public:
	//Active Server Pages Methods
	STDMETHOD(OnStartPage)(IUnknown* IUnk);
	STDMETHOD(OnEndPage)();
	STDMETHOD(put_Key)(const BSTR bstrNewVal);
	STDMETHOD(put_InitialVector)(const BSTR bstrNewVal);
	STDMETHOD(encrypt)(const BSTR bstrValue, BSTR* pbstrReturn);
	STDMETHOD(decrypt)(const BSTR bstrValue, BSTR* pbstrReturn);
	STDMETHOD(sha256)(const BSTR bstrValue, BSTR* pbstrReturn);
private:
	CComPtr<IRequest> m_piRequest;					//Request Object
	CComPtr<IResponse> m_piResponse;				//Response Object
	CComPtr<ISessionObject> m_piSession;			//Session Object
	CComPtr<IServer> m_piServer;					//Server Object
	CComPtr<IApplicationObject> m_piApplication;	//Application Object
	BOOL m_bOnStartPageCalled;						//OnStartPage successful?

	#define STRENCRYPTER_KEY_SIZE					16							// Key size (16 bytes)	
	#define STRENCRYPTER_KEY_BIT_SIZE				(STRENCRYPTER_KEY_SIZE * 8) // Key size in bit
	#define	STRENCRYPTER_BLOCK_SIZE					16							// Block size (16 bytes)
	
	// Whether the key or the initial vector is modified
	BOOL	m_bTouched ;
	BSTR	m_bstrKey ;
	BSTR	m_bstrInitialVector ;
	BYTE	m_pbyHashedKey[STRENCRYPTER_KEY_SIZE] ;
	BYTE	m_pbyHashedInitialVector[STRENCRYPTER_BLOCK_SIZE] ;

	/*! \brief	Initializes internal states. */
	HRESULT _Initialize (void) throw () ;

	/*! \brief	Reports error information. */
	static void _Error (LPCOLESTR szMessage) throw () ;
	/*! \brief	Reports error information. */
	static void _Error (LPCOLESTR szMessage, DWORD dwErrCode) throw () ;

	/*! \brief	Converts an unicode string into a UTF-8 byte array. */
	static HRESULT _ToUtf8 (const BSTR bstrValue, BYTE ** ppbyOutput, int * pcbyOutput) throw () ;
	/*! \brief	Converts a UTF-8 byte array into an unicode string. */
	static HRESULT _FromUtf8 (const BYTE * pbyUtf8, const int cbyUtf8, BSTR * pbstrOutput) throw () ;

	/*! \brief	Encodes data according to the PKCS7 padding algorithm. */
	static HRESULT _ToPkcs7 (const BYTE * pbyValue, int cbyValue, BYTE ** ppbyOutput, int * pcbyOutput) throw () ;
	/*! \brief	Gets an actual size of data encoded by PKCS7 padding algorithm. */
	static HRESULT _GetActualSizeOfPkcs7 (const BYTE * pbyPkcs7, int cbyPkcs7, int * piSize) throw () ;

	/*! \brief	Gets the MD5 hash. */
	static HRESULT _ToMd5 (const BYTE * pbyValue, int cbyValue, BYTE * pbyBuffer) throw () ;

	/*! \brief	Converts a binary data into a Base64 encoded string. */
	static HRESULT _ToBase64 (const BYTE * pbyValue, int cbyValue, BSTR * pbstrOutput) throw () ;
	/*! \brief	Converts a Base64 encoded string into a binary data. */
	static HRESULT _FromBase64 (const BSTR bstrBase64, BYTE ** ppbyOutput, int * pcbyOutput) throw () ;

#ifndef SAFEFREE
#	define SAFEFREE(x) if(x){ ::free((void *)x); x = NULL; }
#endif
};

OBJECT_ENTRY_AUTO(__uuidof(Epart), CEpart)
